// 类型标注
/* let str:string = '你好世界'
str = 100 */
// any代表任意类型
/* let a:any = '你好世界';
a = 200;
console.log(a);
 */

// unknown 
/* let a:unknown = '你好世界';
a = 100;
console.log(a);
 */
/* 
  数组类型
  1 使用语法糖定义数组  数组的每个值要求是固定的类型
*/
/* const arr: number[] = [2,4,56,7];

arr.push('你好世界') */
// 2 使用泛型定义数组
/* const arr: Array<number> = [1,2,3,4];
arr.push('你好世界') */

/* 
  元祖类型
  特殊数组，每个值得类型可以不一样
*/

// const tp: [number, string] = [10, '你好世界', 200];



// 定义函数
/* function fn(a: string, b: string):string{
  return a + b
}
fn('hello', 'world') */
// void 类型 标注函数 没有返回值
/* function fn(a: string, b: string):void{
  console.log(a+b);
  
}

fn('hello', 'world') */

/* const fn = (a: number, b: number):number => {
  return a+b;
}

fn(10, 20) */

// 可选参数要求必须是 最后一个参数
/* function fn (x: number, y?: number): number {
  return x;
}

fn(10) */

// 定义参数的默认值 任意一个未知的 形参都可以有默认值 （不传使用undefined占位）
/* function fn(a: number,b:number = 20, c: number):void {
  console.log(a);
  console.log(b);
  console.log(c);
}
fn(10, undefined, 30);
 */

// object 类型 标注 功能较弱，只能标注 类型是对象，但是对象结构无法标注

/* 
  接口  interface 自定义类型 
  用来 标注 描述 对象结构 和 函数结构
*/

/* interface Person {
  name: string;
  age: number;
  gender: number

}

const p1: Person = {
  name: '小明',
  age: 19,
  gender:1
}
console.log(p1); */

// 接口可选属性
/* interface Person {
  name: string;
  age: number;
  gender?: number
}

const p1: Person = {
  name: '小明',
  age: 19,
  gender: 0
}
console.log(p1); */

// 接口只读属性
/* interface Person {
  readonly id: number;
  name: string;
  age: number;
  gender?: number
}

const p1: Person = {
  id: 11,
  name: '小明',
  age: 19,
  gender: 0
}
p1.id = 222; */

// 接口描述函数类型
/* interface Fn{
  (a: number, b: number): void
}

function fn (a: string, b: number, c: Fn) :void {
  c(10, 30)
}
fn('aaa', 10, function(a:number, b:number):number{
  console.log(a+b);
  
}) */

// 枚举类型
/* enum Direction {
  north = '哈哈',
  south = '嘿嘿',
  east = '嘻嘻',
  west = '呵呵'
}
// 以对象形式来使用 得到的是  下标
console.log(Direction.north);
console.log(Direction.south);

console.log(Direction.south);
 */

// 类型推论
/* let a = 10;

a = '你好世界';
console.log(a);
 */
// 推论成any类型
/* let a;
a = 10;
a = '你的味道哇';
console.log(a);
 */
// 函数形参的类型推论 和返回值的类型推论
/* function fn(x = 10) {
  console.log(x);
  
}
fn('你好') */

// 联合类型 一个变量值得类型可以是多个
/* let a: number|string = 10;
a = '你好'
console.log(a);
 */


/* 
  联合类型的 类型保护
  一个变量是联合类型时， 使用 变量 什么类型的api都报错
  解决方案：
    类型断言
     使用联合类型 某个api 告诉ts 我知道我在干啥，（后续会传对应的类型的值）

     值 as 类型
*/
/* function fn(a: string|number){
  const str = a as string;
  if (str.length) {
    console.log(str.length);
  }
  const num = a as number;
  if (num.toFixed) {
    console.log(num.toFixed(2));
    
  } 
}

fn('hello world') */

/* 
type str = string;
const a: str = 1000;
console.log(a);
 */

// 接口 也可以直接字面量的形式
/* const obj: {name: string;age: number} = {
  name: '小明',
  age: 19
} */

/* type Person = {
  name: string;
  age: number
}
const obj: Person = {
  name: '小明',
  age: 18
} */

/* function fn<T>(n: T): T{
  return n
}

fn<number>(10) */
